home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / LU-2.5B / vs / vsem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-23  |  26.4 KB  |  952 lines  |  [TEXT/MPS ]

  1. #ifdef lint
  2. static char *SCCSid = "%W%    (NCSA)    %G%";
  3. #endif
  4.  
  5. /*
  6.  *
  7.  *      Virtual Screen Kernel Emulation Routines
  8.  *                      (vsem.c)
  9.  *  
  10.  *   National Center for Supercomputing Applications
  11.  *      by Gaige B. Paulsen
  12.  *
  13.  *    This file contains the private emulation calls for the NCSA
  14.  *  Virtual Screen Kernel.
  15.  *
  16.  *      Version Date    Notes
  17.  *      ------- ------  ---------------------------------------------------
  18.  *      0.01    861102  Initial coding -GBP
  19.  *      0.10    861111  Added/Modified VT emulator -GBP
  20.  *      0.50    861113  First compiled edition -GBP
  21.  *        2.1        871130    NCSA Telnet 2.1 -GBP
  22.  *        2.2     880715    NCSA Telnet 2.2 -GBP
  23.  */
  24.  
  25. #include <QuickDraw.h>
  26. #include <Controls.h>
  27.  
  28. #include "vsdata.h"
  29. #include "vskeys.h"
  30. #include "rsmac.h"
  31. #include "vsinterf.h"        /* BYU 2.4.18 */
  32. #include "vsintern.h"
  33.  
  34.  
  35. #include "::main:LUU.h"        /* Needs these includes. Mostly for LU print routines /Bug */
  36. #include <PrintTraps.h>
  37. #include <Fonts.h>
  38. #include "::main:configrec.h"
  39. #include "::main:maclook.h"
  40. #include <OSUtils.h>
  41. #include <ToolUtils.h>
  42. #include <Files.h>
  43. #include <Memory.h>
  44. #include "vsinterf.h"
  45. #include "::main:event.h"    /* updateCursor() */
  46. #include <Strings.h>
  47.  
  48. /* LU originally modified PrintPages, but it's nicer to have a separate
  49.    function, if U ask me. All this to vsem is LU, more or less.. /Bug */
  50.  
  51. void
  52.     printsleep();            /* The netsleep/ print cancel procedure (menu.c) */
  53.  
  54. #define ascLF 10
  55. #define ascFF 12
  56. #define ascCR 13
  57. #define PGRECT    (*prRecHdl)->prInfo.rPage        /* Macro for making the pagerect more accessible */
  58. #define PAPRECT    (*prRecHdl)->rPaper                /* Macro for making the paperrect more accessible */
  59. #define bDevCItoh     1        /* from PrintTraps.h */
  60.  
  61. extern THPrint prRecHdl;        /* our print record handle from menu.c LU /Bug */
  62. extern SysEnvRec theWorld;        /* System Environment record from environ.c LU */
  63. extern Cursor *normcurs;        /* Cursor for non-transfer normal mode from maclook.c LU*/
  64. extern char
  65.     stupidarray[150];        /* A stupid array for finding the StringWidth (from menu.c) */
  66.  
  67.  
  68. /*
  69.  *    printFile(prPort, columns, refNum) -
  70.  *            Prints <file <refNum> on the printer through port <prPort>
  71.  *             using <columns>.
  72.  *  Note:    It expects file position to be 3 chars after what it should print!
  73.  *            Should be changed to take parameters with length to print and
  74.  *            offset in file, or something. /Bug
  75.  *
  76.  */
  77. void printFile(prPort, columns, refNum)
  78. TPPrPort prPort;        /* the Printer port */
  79. int columns;
  80. short refNum;
  81. {
  82.     char *start;
  83.     long charlen,count=0L;
  84.     int v, h, scount, lines, pgcount, maxlines;
  85.     FMetricRec info;
  86.     int Fheight, Fwidth;
  87.     unsigned char buf[256];        /* to build a line in from the file */
  88.     unsigned char nextchar;        /* next unprocessed char in file */
  89.     int rdy;
  90.     short indent;                /* indent to give reasonable left marginal */
  91.     OSErr sts;
  92.     long dummyCount;
  93.     char tmp[100];                /* only for debugging */
  94.  
  95.     putln("in printFile()");
  96.     sprintf(tmp,"prPort:%08x",prPort); putln(tmp);
  97.     sprintf(tmp,"columns:%d",columns); putln(tmp);
  98.     sprintf(tmp,"refNum:%04x",refNum); putln(tmp);
  99.     
  100.     sprintf (tmp,"rPage top,left:%d,%d bot,right:%d,%d",PGRECT.top,PGRECT.left,PGRECT.bottom,PGRECT.right);putln(tmp);
  101.     sprintf (tmp,"rPaper top,left:%d,%d bot,right:%d,%d",PAPRECT.top,PAPRECT.left,PAPRECT.bottom,PAPRECT.right);putln(tmp);
  102.     sprintf (tmp,"rPage iVRes:%d iHRes:%d",(*prRecHdl)->prInfo.iVRes,(*prRecHdl)->prInfo.iHRes);putln(tmp);
  103.  
  104.     indent = ((*prRecHdl)->prInfo.iHRes * 180)/254;     /* 1.8 centimeters left margin */
  105.     if (-PAPRECT.left > indent)
  106.         indent = 0;
  107.     else
  108.         indent += PAPRECT.left;
  109.     sprintf(tmp,"indent:%d",indent); putln(tmp);
  110.  
  111.     if ( ((*prRecHdl)->prStl.wDev>>8) == bDevCItoh ) {
  112.                     /* Think about this: put def. font in rsrc fork- STR255 */
  113.         TextFont(monaco);            /* gives monaco on ImageWriters … */
  114.         v=9;
  115.         }
  116.     else {
  117.         TextFont(courier);            /* … and courier on others (incl LW SC) */
  118.         v=14;
  119.         }
  120.  
  121.     do {
  122.         TextSize(v);
  123.         FontMetrics( &info );
  124.         Fheight = FixRound( info.ascent + info.descent + info.leading);
  125.         Fwidth  = FixRound( info.widMax);
  126.         Fwidth  = CharWidth('W');            /* Re-assign to largest char */
  127.         v--;
  128.     } while ( TextWidth( stupidarray,0,columns+1) > (PGRECT.right - PGRECT.left - indent));
  129.     sprintf (tmp,"Fheight:%d, Fwidth:%d, TextSize:%d",Fheight,Fwidth,v+1); putln (tmp);
  130.  
  131.     if (sts=GetFPos(refNum, &charlen))
  132.         { sprintf(tmp,"GetFPos: ERROR %d",sts); putln(tmp); }
  133.     charlen-=3;                    /* skip last 3 chars, as they are part of ESC seq */
  134.     if (sts=SetFPos(refNum,(short) fsFromStart,0L))    /* rewind to beginning of file */
  135.         { sprintf(tmp,"SetFPos: ERROR %d",sts); putln(tmp); }
  136.     start = buf;
  137.     dummyCount=1;
  138.     if (sts=FSRead(refNum,&dummyCount,&nextchar))        /* get first char */
  139.         { sprintf(tmp,"FSRead: ERROR %d",sts); putln(tmp); }
  140.  
  141.     sprintf(tmp,"chars to print:%d",charlen); putln(tmp);
  142.     
  143.     h=PGRECT.right - PGRECT.left - indent;    /* Get the width */
  144.     v=PGRECT.bottom- PGRECT.top;            /* Get the height */
  145.  
  146.     maxlines = v/Fheight-1;
  147.     pgcount = 0;
  148.     while (count<charlen) {
  149.         pgcount++;
  150.         lines = 1;
  151.         PrOpenPage(prPort, 0L);        /* Open the Printer Page */
  152.         if (sts=PrError()) { sprintf(tmp,"PrOpenPage: ERROR %d",sts); putln(tmp); }
  153.         (*prRecHdl)->prJob.pIdleProc= (PrIdleProcPtr) printsleep;    /* our netsleep */
  154.         sprintf (tmp,"printing page:%d",pgcount); putln(tmp);
  155.  
  156.         /* print from file */
  157.         while (lines <= maxlines && count<charlen) {
  158.             rdy = 0;
  159.             scount = 0;
  160.             while ((count<charlen) && (!rdy)) {
  161.                 switch (nextchar) {
  162.                     case ascCR:
  163.                         rdy=1;
  164.                         break;
  165.                     case ascLF:
  166.                         rdy=1;
  167.                         break;
  168.                     case ascFF:
  169.                         rdy=1;
  170.                         break;
  171.                     default:
  172.                         buf[scount++]=nextchar;
  173.                         count++;
  174.                         dummyCount=1;
  175.                         if (sts=FSRead (refNum,&dummyCount,&nextchar))
  176.                             { sprintf(tmp,"FSRead: ERROR %d",sts); putln(tmp); }
  177.                         break;
  178.                 }
  179.             }
  180.             MoveTo(indent,lines*Fheight);
  181.             if (scount>0)
  182.                 DrawText(start, 0, scount);
  183.             if (nextchar==ascLF)
  184.                 lines++;                        /* LF -> new line */
  185.             if (nextchar==ascFF)
  186.                 lines = maxlines+1;                /* FF -> new page */
  187.             dummyCount=1;
  188.             if (sts=FSRead (refNum,&dummyCount,&nextchar))
  189.                 { sprintf(tmp,"FSRead: ERROR %d",sts); putln(tmp); }
  190.             count++;
  191.         }
  192.  
  193.         PrClosePage(prPort);        /* Close the Printer page */
  194.         if (sts=PrError()) { sprintf(tmp,"PrClosePage: ERROR %d",sts); putln(tmp); }
  195.     }
  196.  
  197.     putln("leaving printFile()");
  198. }
  199.  
  200. void VSprON()
  201. {
  202.     char tmp[100];                /* only for debugging */
  203.     OSErr sts;
  204.     
  205.     putln ("printer redirection ON");
  206.     VSIw->prredirect = 1;
  207.     VSIw->prbuf = 0x00000000;
  208.     sprintf (VSIw->fname,"NCSA Telnet tempfile #%d",VSIwn);
  209.     (void) c2pstr(VSIw->fname);
  210.     if (sts=Create (VSIw->fname,theWorld.sysVRefNum,'EDIT','TEXT')) {
  211.         SysBeep(1);
  212.         /* Now, if there already is a temporary file, the Create call fails.
  213.            Then it just continues through the script until the end, where it
  214.            doesn't try to close the file (since there was an error condition
  215.            before. That results in the same thing next printout!!!)
  216.            Just try to delete file and do it again. Stupid but robust(?) BUG 910731 */
  217.         sprintf(tmp,"Create : ERROR %d",sts); putln(tmp);
  218.         sts=FSDelete(VSIw->fname,theWorld.sysVRefNum); /* Resultcode? What me worry? */
  219.  
  220.         if (sts=Create (VSIw->fname,theWorld.sysVRefNum,'EDIT','TEXT')) {
  221.             SysBeep(1);
  222.             VSIw->prredirect = 0;
  223.             sprintf(tmp,"Create : ERROR %d",sts); putln(tmp);
  224.             return;
  225.         }
  226.     }
  227.     if (sts=FSOpen (VSIw->fname,theWorld.sysVRefNum,&(VSIw->refNum))) {
  228.         SysBeep(1);
  229.         VSIw->prredirect = 0;
  230.         sprintf(tmp,"FSOpen: ERROR %d",sts); putln(tmp);
  231.         FSDelete (VSIw->fname,theWorld.sysVRefNum);
  232.         return;
  233.     }
  234. }
  235.  
  236.  
  237. void VSprOFF()
  238. {
  239.     Str255 Title;
  240.     TPrStatus prStatus;        /* Status record */
  241.     TPPrPort prPort;        /* the Printer port */
  242.     OSErr sts;
  243.     GrafPtr    savePort;
  244.     char tmp[100];            /* only for debugging */
  245.  
  246.     putln ("printer redirection OFF");
  247.     if (VSIw->prredirect==0)            /* no redirection started! */
  248.         return;
  249.     VSIw->prredirect = 0;
  250.     GetPort (&savePort);                /* save old port */
  251.  
  252.     if (prRecHdl==0L) {                    /* Make sure print is inited */
  253.         PrOpen();
  254.         if (sts=PrError()) { sprintf(tmp,"PrOpen: ERROR %d",sts); putln(tmp); }
  255.         prRecHdl=(THPrint)NewHandle((long)sizeof(TPrint));
  256.         PrintDefault(prRecHdl);
  257.         if (sts=PrError()) { sprintf(tmp,"PrintDefault: ERROR %d",sts); putln(tmp); }
  258.     }
  259.  
  260.     GetWTitle ((GrafPtr) RSgetwindow(VSIwn),&Title);
  261.     SetCursor(normcurs);
  262.     
  263.     if (PrJobDialog(prRecHdl)) {            /* Cancel the print if FALSE */
  264.         if (sts=PrError()) { sprintf(tmp,"PrJobDialog: ERROR %d",sts); putln(tmp); }
  265.         prPort=PrOpenDoc(prRecHdl,0L,0L);
  266.         if (sts=PrError()) {
  267.             SysBeep(1);
  268.             sprintf(tmp,"PrOpenDoc: ERROR %d",sts); putln(tmp);
  269.         } else {
  270.             printFile (prPort, VSmaxwidth(VSIwn), VSIw->refNum);
  271.             PrCloseDoc(prPort);
  272.             if (sts=PrError()) { sprintf(tmp,"PrCloseDoc: ERROR %d",sts); putln(tmp); }
  273.             if (((*prRecHdl)->prJob.bJDocLoop == bSpoolLoop) && (PrError()==0)) {
  274.                 PrPicFile(prRecHdl,0L,0L,0L,&prStatus); /* Spool if necessary… */
  275.                 if (sts=PrError()) { sprintf(tmp,"PrPicFile: ERROR %d",sts); putln(tmp); }
  276.             }
  277.         }
  278.     }
  279.     SetPort (savePort);                /* restore old port */
  280.     if (sts=FSClose (VSIw->refNum)) {
  281.         SysBeep(1);
  282.         sprintf(tmp,"FSClose: ERROR %d",sts); putln(tmp);
  283.     }
  284.     VSIw->refNum = -1;
  285.     if (sts=FSDelete (VSIw->fname,theWorld.sysVRefNum)) {
  286.         SysBeep(1);
  287.         sprintf(tmp,"FSDelete: ERROR %d",sts); putln(tmp);
  288.     }
  289.     updateCursor(1);
  290. }
  291.  
  292.  
  293. #define ENDOFPRT     '\033[4i'        /* <ESC>[4i   (0x1b5b3469) */
  294.  
  295. void VSpr(pc,pctr)
  296. int *pctr;
  297. unsigned char **pc;
  298. {
  299.     long count;                /* number of chars to print to file */
  300.     char *start;             /* original start of buffer */
  301.     OSErr sts;
  302.     char tmp[100];            /* only for debugging */
  303.     int rdy;                /* true if <ESC>[4i */
  304.  
  305.     count=0;                
  306.     start=*pc;    
  307.     rdy=0;
  308.  
  309.     while ((*pctr>0) && (!rdy)) {
  310.         VSIw->prbuf=(VSIw->prbuf<<8) + **pc;
  311.         if (VSIw->prbuf==ENDOFPRT) {            /* i.e. no more redirection */
  312.             rdy=1;
  313.             count--;                    /* will be incremented again below */
  314.         }
  315.         count++;
  316.         (*pc)++;
  317.         (*pctr)--;
  318.     }
  319.  
  320.     trbuf7to8 (start,count);
  321.     if (sts=FSWrite(VSIw->refNum,&count,start)) {
  322.         SysBeep(1);
  323.         sprintf(tmp,"FSWrite: ERROR %d",sts); putln(tmp);
  324.     }
  325.     if (rdy || sts)
  326.         VSprOFF();
  327. }
  328.  
  329. /*   End of LU & Bug strangeness /Bug  */
  330.  
  331.  
  332.  
  333.  
  334. void VSem
  335.   (
  336.       /* Complains about declaring these register when using &ctr, &ctr as
  337.        parameters when calling VSpr. /Bug */
  338.      /* register */ unsigned char *c, /* pointer to character string */
  339.      /* register */ int ctr /* length of character string */
  340.   )
  341.   /* basic routine for placing characters on a virtual screen, and
  342.     interpreting control characters and escape sequences. Simple
  343.     interpretation of controls & escapes is done here, while the
  344.     harder stuff is done by calling VSIxx routines in vsintern.c. */
  345.   {
  346.     register int sx;
  347.     register int escflg; /* state of escape sequence interpretation */
  348.     int insert, attrib, extra, offend;
  349.     char *acurrent, *current, *start;
  350.  
  351.     escflg = VSIw->escflg;
  352.  
  353.     while (ctr > 0)
  354.       {
  355.  
  356.         /* NOTE: Do not capture things that go to the printer! Should it?!? LU /Bug */
  357.         if (VSIw->prredirect)    /* printer redirection? LU /Bug */
  358.             VSpr(&c,&ctr);        /* if yes, call VSpr */
  359.                                 /* when we return from VSpr there may be (ctr!=0) … */
  360.                                 /* … or may not (ctr==0) be chars left in *c to print */
  361.  
  362.         while ((escflg == 0) && (ctr > 0) && (*c < 32))
  363.           {
  364.             switch (*c)
  365.               {
  366.                 case 0x1b: /* esc */
  367.                     escflg++;
  368.                     break;
  369.                 case 0x0e: /* shift out */
  370.                     if (VSIw->G1)
  371.                         VSIw->attrib = VSgraph(VSIw->attrib);
  372.                     else
  373.                         VSIw->attrib = VSnotgraph(VSIw->attrib);
  374.                     VSIw->charset = 1;
  375.                     break;
  376.                 case 0x0f: /* shift in */
  377.                     if (VSIw->G0)
  378.                         VSIw->attrib = VSgraph(VSIw->attrib);
  379.                     else
  380.                         VSIw->attrib = VSnotgraph(VSIw->attrib);
  381.                     VSIw->charset = 0;
  382.                     break;
  383.                 case 0x07: /* bell */
  384.                     RSbell(VSIwn);
  385.                     break;
  386.                 case 0x08: /* backspace */
  387.                     VSIw->x--;
  388.                     if (VSIw->x < 0)
  389.                       /* hit left margin */
  390.                         VSIw->x = 0;
  391.                     break;
  392.                 case 0x0c: /* ff */
  393.                     VSIindex();
  394.                     break;
  395.                 case 0x09: /* ht */        /* Later change for versatile tabbing */
  396.                     VSItab();
  397.                     VScapture(c,1);                /* BYU 2.4.18 */
  398.                     break;
  399.                 case 0x0a: /* lf */
  400.                     VSIindex();
  401.                     break;
  402.                 case 0x0d: /* cr */
  403.                     VSIw->x = 0;
  404.                     VScapture(c,1);                /* BYU 2.4.18 */
  405.                     break;
  406.                 case 0x0b: /* vt */
  407.                     VSIindex();
  408.                     break;
  409. #ifdef CISB
  410.                 case 0x10: /* dle */
  411.                     bp_DLE(c, ctr);
  412.                     ctr = 0;
  413.                     break;
  414.                 case 0x05: /* enq */
  415.                     bp_ENQ();
  416.                     break;
  417. #endif CISB
  418.               } /* switch */
  419.             c++;
  420.             ctr--;
  421.           } /* while */
  422.         if ((escflg == 0) && (ctr > 0) && (*c & 0x80))    /* BYU 2.4.12 - VT220 starts here */
  423.           {                                                /* BYU 2.4.12 */
  424.             switch (*c)                                    /* BYU 2.4.12 */
  425.               {                                            /* BYU 2.4.12 */
  426.                 case 0x84: /* ind */            /* BYU 2.4.12 - same as ESC D */
  427.                     VSIindex();                    /* BYU 2.4.12 */
  428.                     goto ShortCut;                /* BYU 2.4.12 */
  429.                 case 0x85: /* nel */            /* BYU 2.4.12 - same as ESC E */
  430.                     VSIw->x = 0;                /* BYU 2.4.12 */
  431.                     VSIindex();                    /* BYU 2.4.12 */
  432.                     goto ShortCut;                /* BYU 2.4.12 */
  433.                 case 0x88: /* hts */            /* BYU 2.4.12 - same as ESC H */
  434.                     VSIw->tabs[VSIw->x] = 'x';    /* BYU 2.4.12 */
  435.                     goto ShortCut;                /* BYU 2.4.12 */
  436.                 case 0x8d: /* ri */                /* BYU 2.4.12 - same as ESC M */
  437.                     VSIrindex();                /* BYU 2.4.12 */
  438.                     goto ShortCut;                /* BYU 2.4.12 */
  439.                 case 0x9b: /* csi */            /* BYU 2.4.12 - same as ESC [ */
  440.                     VSIapclear();                /* BYU 2.4.12 */
  441.                     escflg = 2;                    /* BYU 2.4.12 */
  442.                     break;                        /* BYU 2.4.12 */
  443.                 case 0x86: /* ssa */            /* BYU 2.4.12 - same as ESC F */
  444.                 case 0x87: /* esa */            /* BYU 2.4.12 - same as ESC G */
  445.                 case 0x8e: /* ss2 */            /* BYU 2.4.12 - same as ESC N */
  446.                 case 0x8f: /* ss3 */            /* BYU 2.4.12 - same as ESC O */
  447.                 case 0x90: /* dcs */            /* BYU 2.4.12 - same as ESC P */
  448.                 case 0x93: /* sts */            /* BYU 2.4.12 - same as ESC S */
  449.                 case 0x96: /* spa */            /* BYU 2.4.12 - same as ESC V */
  450.                 case 0x97: /* epa */            /* BYU 2.4.12 - same as ESC W */
  451.                 case 0x9d: /* osc */            /* BYU 2.4.12 - same as ESC ] */
  452.                 case 0x9e: /* pm */                /* BYU 2.4.12 - same as ESC ^ */
  453.                 case 0x9f: /* apc */            /* BYU 2.4.12 - same as ESC _ */
  454.                     goto ShortCut;                /* BYU 2.4.12 */
  455.               } /* switch */                    /* BYU 2.4.12 */
  456.             c++;                                /* BYU 2.4.12 */
  457.             ctr--;                                /* BYU 2.4.12 */
  458.           } /* if */                            /* BYU 2.4.12 */
  459.         while ((ctr > 0) && (escflg == 0) && (*c >= 32))
  460.           {
  461.           /* display printing characters */
  462.             start = &VSIw->linest[VSIw->y]->text[VSIw->x]; /* start of area needing redrawing */
  463.             current = start; /* where to put next char */
  464.             acurrent = &VSIw->attrst[VSIw->y]->text[VSIw->x]; /* where to put corresponding attribute byte */
  465.             attrib = VSIw->attrib; /* current writing attribute */
  466.             insert = VSIw->IRM; /* insert mode (boolean) */
  467.             offend = 0; /* wrapped to next line (boolean) */
  468.             extra = 0; /* overwriting last character of line (boolean) */
  469.             sx = VSIw->x; /* starting column of area needing redrawing */
  470.             if (VSIw->x > VSIw->maxwidth)
  471.               {
  472.                 if (VSIw->DECAWM)
  473.                   {
  474.                   /* wrap to next line */
  475.                     VSIw->x = 0;
  476.                     VSIindex();
  477.                   }
  478.                 else
  479.                   /* stay at right margin */
  480.                     VSIw->x = VSIw->maxwidth;
  481.                 current = start = &VSIw->linest[VSIw->y]->text[VSIw->x];
  482.                 acurrent = &VSIw->attrst[VSIw->y]->text[VSIw->x];
  483.                 sx = VSIw->x;
  484.               } /* if */
  485.             while ((ctr > 0) && (*c >= 32) && (offend == 0))
  486.               {
  487.               /* write characters within a single line */
  488.                 if (insert)
  489.                   /* make room for the char */
  490.                     VSIinschar(1);
  491.  
  492.                 trbuf7to8(c,1);    /* Translate to Mac 8-bit for the screen.  LU /Bug */
  493.  
  494.               /* poke the character and its attribute into the
  495.                 screen buffer at the current cursor position */
  496.                 *current = *c;
  497.                 *acurrent = attrib;
  498.                 c++;
  499.                 ctr--;
  500.                 if (VSIw->x < VSIw->maxwidth)
  501.                   {
  502.                   /* advance the cursor position */
  503.                     acurrent++;
  504.                     current++;
  505.                     VSIw->x++;
  506.                   }
  507.                 else
  508.                   {
  509.                   /* hit right margin */
  510.                     if (VSIw->DECAWM)
  511.                       {
  512.                       /* autowrap to start of next line */
  513.                         VSIw->x++;
  514.                         offend = 1; /* terminate inner loop */
  515.                       }
  516.                     else
  517.                       {
  518.                       /* stay at right margin */
  519.                         VSIw->x = VSIw->maxwidth;
  520.                         extra = 1; /* cursor position doesn't advance */
  521.                       } /* if */
  522.                   } /* if */
  523.               } /* while */
  524.           /* update the screen to show what I've done */
  525.               extra += VSIw->x - sx + offend;                                    /* BYU 2.4.18 */
  526.             if (insert)
  527.                 VSIinsstring(extra, start);                                    /* BYU 2.4.18 */
  528.                                     /* actually just decides which RS to use */
  529.             else
  530.                 VSIdraw(VSIwn, sx, VSIw->y, VSIw->attrib, extra, start);    /* BYU 2.4.18 */
  531.             VScapture((unsigned char *) start, extra);                        /* BYU 2.4.18 */
  532.           } /* while */
  533.  
  534.         while((ctr > 0) && (escflg == 1))
  535.           { /* basic escape sequence processing */
  536.             switch (*c)
  537.               {
  538.                 case 0x08:
  539.                     VSIw->x--;
  540.                     if (VSIw->x < 0)
  541.                         VSIw->x = 0;
  542.                     break;
  543.                 case '[': /* csi */
  544.                     VSIapclear();
  545.                     escflg++;
  546.                     break;
  547.                 case '7':
  548.                     VSIsave();
  549.                     goto ShortCut;                /* BYU 2.4.12 */
  550.                 case '8':
  551.                     VSIrestore();
  552.                     goto ShortCut;                /* BYU 2.4.12 */
  553.                 case 'c':
  554.                     VSIreset();
  555.                     break;
  556.                 case 'D':
  557.                     VSIindex();
  558.                     goto ShortCut;                /* BYU 2.4.12 */
  559.                 case 'E':
  560.                     VSIw->x = 0;
  561.                     VSIindex();
  562.                     goto ShortCut;                /* BYU 2.4.12 */
  563.                 case 'M':
  564.                     VSIrindex();
  565.                     goto ShortCut;                /* BYU 2.4.12 */
  566.                 case '>':
  567.                     VSIw->DECPAM = 0;
  568.                     goto ShortCut;                /* BYU 2.4.12 */
  569.                 case '=':
  570.                     VSIw->DECPAM = 1;
  571.                     goto ShortCut;                /* BYU 2.4.12 */
  572.                 case 'Z':
  573.                     VTsendident();
  574.                     goto ShortCut;                /* BYU 2.4.12 */
  575.                 case ' ':                        /* BYU 2.4.12 */
  576.                 case '*':                        /* BYU 2.4.12 */
  577.                 case '#':
  578.                     escflg = 3;
  579.                     break;
  580.                 case '(':
  581.                     escflg = 4;
  582.                     break;
  583.                 case ')':
  584.                     escflg = 5;
  585.                     break;
  586.                 case 'H':
  587.                     VSIw->tabs[VSIw->x] = 'x';
  588.                     goto ShortCut;                /* BYU 2.4.12 */
  589. #ifdef CISB
  590.                 case 'I':
  591.                     bp_ESC_I();
  592.                     break;
  593. #endif CISB
  594.                 default:
  595.                     goto ShortCut;                /* BYU 2.4.12 */
  596.               } /* switch */
  597.             c++;
  598.             ctr--;
  599.           } /* while */
  600.         while ((escflg == 2) && (ctr > 0))
  601.           { /* "control sequence" processing */
  602.             switch (*c)
  603.               {
  604.                 case 0x08:
  605.                     VSIw->x--;
  606.                     if (VSIw->x < 0)
  607.                         VSIw->x = 0;
  608.                     break;
  609.                 case '0':
  610.                 case '1':
  611.                 case '2':
  612.                 case '3':
  613.                 case '4':
  614.                 case '5':
  615.                 case '6':
  616.                 case '7':
  617.                 case '8':
  618.                 case '9':
  619.                   /* parse numeric parameter */
  620.                     if (VSIw->parms[VSIw->parmptr] < 0)
  621.                         VSIw->parms[VSIw->parmptr] = 0;
  622.                     VSIw->parms[VSIw->parmptr] = VSIw->parms[VSIw->parmptr] * 10;
  623.                     VSIw->parms[VSIw->parmptr] += *c - '0';
  624.                     break;
  625.                 case '?':
  626.                   /* DEC-private control sequence */
  627.                     VSIw->parms[VSIw->parmptr++] = -2;
  628.                     break;
  629.                 case ';':
  630.                   /* parameter separator */
  631.                     VSIw->parmptr++;
  632.                     break;
  633.                 case 'A': /* cursor up */
  634. #if 1                                                        /* BYU */
  635.                     if (VSIw->parms[0]<1) VSIw->y--;        /* BYU */
  636.                     else VSIw->y-=VSIw->parms[0];            /* BYU */
  637.                     if ( VSIw->y < 0 ) VSIw->y=0;            /* BYU */
  638. #else                                                        /* BYU */
  639.                     if (VSIw->y < VSIw->top)
  640.                       {
  641.                       /* outside scrolling region */
  642.                         if (VSIw->parms[0] < 1)
  643.                             VSIw->y--;
  644.                         else
  645.                             VSIw->y -= VSIw->parms[0];
  646.                       }
  647.                     else
  648.                       {
  649.                       /* don't leave scrolling region */
  650.                         if (VSIw->parms[0] < 1)
  651.                             VSIw->y--;
  652.                         else
  653.                             VSIw->y -= VSIw->parms[0];
  654.                         if (VSIw->y < VSIw->top)
  655.                             VSIw->y = VSIw->top;
  656.                       }
  657. #endif                                                        /* BYU */
  658.                     VSIrange();
  659.                     goto ShortCut;                /* BYU 2.4.12 */
  660.                 case 'B': /* cursor down */
  661. #if 1                                                        /* BYU */
  662.                     if (VSIw->parms[0]<1) VSIw->y++;        /* BYU */
  663.                     else VSIw->y+=VSIw->parms[0];            /* BYU */
  664.                     if ( VSIw->y > VSIw->lines )             /* BYU */
  665.                         VSIw->y=VSIw->lines;                /* BYU */
  666. #else                                                        /* BYU */
  667.                     if (VSIw->y > VSIw->bottom)
  668.                       {
  669.                       /* outside scrolling region */
  670.                         if (VSIw->parms[0] < 1)
  671.                             VSIw->y++;
  672.                         else
  673.                             VSIw->y += VSIw->parms[0];
  674.                       }
  675.                     else
  676.                       {
  677.                       /* don't leave scrolling region */
  678.                         if (VSIw->parms[0] < 1)
  679.                             VSIw->y++;
  680.                         else
  681.                             VSIw->y += VSIw->parms[0];
  682.                         if (VSIw->y > VSIw->bottom)
  683.                             VSIw->y = VSIw->bottom;
  684.                       }
  685. #endif                                                        /* BYU */
  686.                     VSIrange();
  687.                     goto ShortCut;                /* BYU 2.4.12 */
  688.                 case 'C': /* cursor right */
  689.                     if (VSIw->parms[0] < 1)
  690.                         VSIw->x++;
  691.                     else
  692.                         VSIw->x += VSIw->parms[0];
  693.                     VSIrange();
  694.                     if (VSIw->x > VSIw->maxwidth)
  695.                         VSIw->x = VSIw->maxwidth;
  696.                     goto ShortCut;                /* BYU 2.4.12 */
  697.                 case 'D': /* cursor left */
  698.                     if (VSIw->parms[0] < 1)
  699.                         VSIw->x--;
  700.                     else
  701.                         VSIw->x -= VSIw->parms[0];
  702.                     VSIrange();
  703.                     goto ShortCut;                /* BYU 2.4.12 */
  704.                 case 'f':
  705.                 case 'H':
  706.                   /* absolute cursor positioning */
  707.                     VSIw->x = VSIw->parms[1] - 1;
  708.                     if (VSIw->DECORG)
  709.                       /* origin mode -- position relative to top of scrolling region */
  710.                         VSIw->y = VSIw->parms[0] - 1 + VSIw->top;
  711.                     else
  712.                         VSIw->y = VSIw->parms[0] - 1;
  713.                     VSIrange();
  714.                     goto ShortCut;                /* BYU 2.4.12 */
  715.  
  716.                 case 'i':                                /* media copy LU /Bug */
  717.                     if (VSIw->parms[VSIw->parmptr]==5) {
  718.                         /*c++; ctr--; */
  719.                         VSprON();    /* set status and open temp file etc */
  720.                                     /* chars will be redirected at top of loop … */
  721.                                     /* … in this procedure */
  722.                     }
  723.                     escflg = 0;
  724.                     break;                                /* End Printer On LU /Bug */
  725.  
  726.                 case 'K':
  727.                   /* erase to beginning/end/whole of line */
  728.                     switch (VSIw->parms[0])
  729.                       {
  730.                         case -1:
  731.                         case  0:
  732.                             VSIeeol();
  733.                             break;
  734.                         case  1:
  735.                             VSIebol();
  736.                             break;
  737.                         case  2:
  738.                             VSIel(-1);
  739.                             break;
  740.                         default:
  741.                             goto ShortCut;        /* BYU 2.4.12 */
  742.                       } /* switch */
  743.                     goto ShortCut;                /* BYU 2.4.12 */
  744.                 case 'J':
  745.                   /* erase to beginning/end/whole of screen */
  746.                     switch (VSIw->parms[0])
  747.                       {
  748.                         case -1:
  749.                         case  0:
  750.                             VSIeeos();
  751.                             break;
  752.                         case  1:
  753.                             VSIebos();
  754.                             break;
  755.                         case  2:
  756.                             VSIes();
  757.                             break;
  758.                         default:
  759.                             goto ShortCut;        /* BYU 2.4.12 */
  760.                       } /* switch */
  761.                     goto ShortCut;                /* BYU 2.4.12 */
  762.                 case 'm':
  763.                   /* set/clear attributes */
  764.                   {
  765.                     int temp = 0;
  766.                     while (temp <= VSIw->parmptr)
  767.                          {
  768.                            if (VSIw->parms[temp] < 1)
  769.                             VSIw->attrib &= 128; /* turn them all off */
  770.                         else if (VSIw->parms[temp] > 20)
  771.           /* turn off the appropriate bit */
  772.                             VSIw->attrib &= ~(1 << (VSIw->parms[temp] - 21));
  773.                             else
  774.           /* turn on the appropriate bit */
  775.                         VSIw->attrib |= 1 << (VSIw->parms[temp] - 1);
  776.                         temp++;
  777.                       } /* while */
  778.                   }
  779.                     goto ShortCut;                /* BYU 2.4.12 */
  780.                 case 'q':
  781.                   /* flash dem LEDs. What LEDs? */
  782.                     goto ShortCut;                /* BYU 2.4.12 */
  783.                 case 'c':
  784.                     VTsendident();
  785.                     goto ShortCut;                /* BYU 2.4.12 */
  786.                 case 'n':
  787.                     switch (VSIw->parms[0])
  788.                       {
  789.                         case 5:
  790.                             VTsendstat();
  791.                             break;
  792.                         case 6:
  793.                             VTsendpos();
  794.                             break;
  795.                       } /* switch */
  796.                     goto ShortCut;                /* BYU 2.4.12 */
  797.                 case 'L':
  798.                     if (VSIw->parms[0] < 1)
  799.                         VSIw->parms[0] = 1;
  800.                     VSIinslines(VSIw->parms[0], -1);
  801.                     goto ShortCut;                /* BYU 2.4.12 */
  802.                 case 'M':
  803.                     if (VSIw->parms[0] < 1)
  804.                         VSIw->parms[0] = 1;
  805.                     VSIdellines(VSIw->parms[0], -1);
  806.                     goto ShortCut;                /* BYU 2.4.12 */
  807.                 case 'P':
  808.                     if (VSIw->parms[0] < 1)
  809.                         VSIw->parms[0] = 1;
  810.                     VSIdelchars(VSIw->parms[0]);
  811.                     goto ShortCut;                /* BYU 2.4.12 */
  812.                 case 'r':
  813.                   /* set scrolling region */
  814.                     if (VSIw->parms[0] < 0)
  815.                         VSIw->top = 0;
  816.                     else
  817.                         VSIw->top = VSIw->parms[0] - 1;
  818.                     if (VSIw->parms[1] < 0)
  819.                         VSIw->bottom = VSIw->lines;
  820.                     else
  821.                         VSIw->bottom = VSIw->parms[1] - 1;
  822.                     if (VSIw->top < 0)
  823.                         VSIw->top = 0;
  824.                     if (VSIw->top > VSIw->lines - 1)
  825.                         VSIw->top = VSIw->lines - 1;
  826.                     if (VSIw->bottom < 1)
  827.                         VSIw->bottom = VSIw->lines;
  828.                     if (VSIw->bottom > VSIw->lines)
  829.                         VSIw->bottom = VSIw->lines;
  830.                     VSIw->x = 0;
  831.                     VSIw->y = 0;
  832.                     if (VSIw->DECORG)
  833.                         VSIw->y = VSIw->top;    /* origin mode relative */
  834.                     goto ShortCut;                /* BYU 2.4.12 */
  835.                 case 'h':
  836.                   /* set options */
  837.                     VSIsetoption(1);
  838.                     goto ShortCut;                /* BYU 2.4.12 */
  839.                 case 'l':
  840.                   /* reset options */
  841.                     VSIsetoption(0);
  842.                     goto ShortCut;                /* BYU 2.4.12 */
  843.                 case 'g':
  844.                     if (VSIw->parms[0] == 3)
  845.                       /* clear all tabs */
  846.                         VSItabclear();
  847.                     else if (VSIw->parms[0] == 0 || VSIw->parms[0] < 0)
  848.                       /* clear tab at current position */
  849.                         VSIw->tabs[VSIw->x] = ' ';
  850.                     goto ShortCut;                /* BYU 2.4.12 */
  851.                 case '!':                        /* BYU 2.4.12 - More private DEC stuff? */
  852.                 case '\'':                        /* BYU 2.4.12 - More private DEC stuff? */
  853.                 case '\"':                        /* BYU 2.4.12 - More private DEC stuff? */
  854.                     escflg++;                    /* BYU 2.4.12 */
  855.                     break;                        /* BYU 2.4.12 */
  856.                 default:            /* Dang blasted strays... */
  857.                     goto ShortCut;                /* BYU 2.4.12 */
  858.               } /* switch */
  859.             c++;
  860.             ctr--;
  861.           } /* while */
  862.     
  863.         while ((escflg == 3) && (ctr > 0))
  864.           {    /* "#" handling */
  865.           /* no support for double-width and double-height characters yet */
  866.             switch (*c)
  867.               {
  868.                 case 0x08:
  869.                     VSIw->x--;
  870.                     if (VSIw->x < 0)
  871.                         VSIw->x = 0;
  872.                     break;
  873.                 case '8': /* alignment display */
  874.                     VTalign();
  875.                     goto ShortCut;                /* BYU 2.4.12 */
  876.                 default:
  877.                     goto ShortCut;                /* BYU 2.4.12 */
  878.               } /* switch */
  879.             c++;
  880.             ctr--;
  881.           } /* while */
  882.  
  883.         while ((escflg == 4) && (ctr > 0))
  884.           {    /* "(" handling (selection of G0 character set) */
  885.             switch (*c)
  886.               {
  887.                 case 0x08:
  888.                     VSIw->x--;
  889.                     if (VSIw->x < 0)
  890.                         VSIw->x = 0;
  891.                     break;
  892.                 case 'A': /* UK */
  893.                 case 'B': /* US */
  894.                 case '1': /* "soft" */
  895.                     VSIw->G0 = 0;
  896.                     if (!VSIw->charset)
  897.                         VSIw->attrib = VSnotgraph(VSIw->attrib);
  898.                     goto ShortCut;                /* BYU 2.4.12 */
  899.                 case '0': /* DEC special graphics */
  900.                 case '2': /* "soft" */
  901.                     VSIw->G0 = 1;
  902.                     if (!VSIw->charset)
  903.                         VSIw->attrib = VSgraph(VSIw->attrib);
  904.                     goto ShortCut;                /* BYU 2.4.12 */
  905.                 default:
  906.                     goto ShortCut;                /* BYU 2.4.12 */
  907.               } /* switch */
  908.             c++;
  909.             ctr--;
  910.           } /* while */
  911.     
  912.         while ((escflg == 5) && (ctr > 0))
  913.           {    /* ")" handling (selection of G1 character set) */
  914.             switch (*c)
  915.               {
  916.                 case 0x08:
  917.                     VSIw->x--;
  918.                     if (VSIw->x < 0)
  919.                         VSIw->x = 0;
  920.                     break;
  921.                 case 'A': /* UK */
  922.                 case 'B': /* US */
  923.                 case '1': /* "soft" */
  924.                     VSIw->G1 = 0;
  925.                     if (VSIw->charset)
  926.                         VSIw->attrib = VSnotgraph(VSIw->attrib);
  927.                     goto ShortCut;                /* BYU 2.4.12 */
  928.                 case '0': /* DEC special graphics */
  929.                 case '2': /* "soft" */
  930.                     VSIw->G1 = 1;
  931.                     if (VSIw->charset)
  932.                         VSIw->attrib = VSgraph(VSIw->attrib);
  933.                     goto ShortCut;                /* BYU 2.4.12 */
  934.                 default:
  935.                     goto ShortCut;                /* BYU 2.4.12 */
  936.               } /* switch */
  937.             c++;
  938.             ctr--;
  939.           } /* while */
  940.     
  941.         if ((escflg > 2) && (ctr > 0))
  942.           {
  943. ShortCut:                        /* BYU 2.4.12 - well, sacrificing style for speed */
  944.             escflg = 0;
  945.             c++;
  946.             ctr--;
  947.           } /* if */
  948.       } /* while (ctr > 0) */
  949.     VSIw->escflg = escflg;
  950.   } /* VSem */
  951.  
  952.